#ifndef Execute_h
#define Execute_h

#include "TMetaProgramms.h"

#define Gen_DECLARATE                           \
typedef Core::TParseArg<Arg_t> Meta_t;          \
typedef typename Meta_t::Strategy_t Strategy_t; \
Meta_t test;


namespace Commands{

class Executer: public ILauncher_t
{
public:
    virtual ~Executer(){ /*std::cout<<"~Executer()\n";*/ delete mLauncher; }

    Executer(ILauncher_t* lau):mLauncher(lau->Copy()){}

    template<class T>
    Executer(T function)
    {
        typedef Core::TArg<T> Arg_t;
        Gen_DECLARATE;
        mLauncher = new Strategy_t( Arg_t(function) );
    }

    template<class T1, class T2>
    Executer(T1 a1, T2 a2)
    {
        typedef Core::TArg<T1,T2> Arg_t;
        Gen_DECLARATE;
        mLauncher = new Strategy_t( Arg_t(a1,a2) );
     }

    template<class T1, class T2, class T3>
    Executer(T1 a1, T2 a2, T3 a3)
    {
        typedef Core::TArg<T1,T2,T3> Arg_t;
        Gen_DECLARATE;
        mLauncher = new Strategy_t( Arg_t(a1,a2,a3) );
    }

    template<class T1, class T2, class T3, class T4>
    Executer(T1 a1, T2 a2, T3 a3, T4 a4)
    {
        typedef Core::TArg<T1,T2,T3,T4> Arg_t;
        Gen_DECLARATE;
        mLauncher = new Strategy_t( Arg_t(a1,a2,a3,a4) );
    }

    template<class T1, class T2, class T3, class T4, class T5>
    Executer(T1 a1, T2 a2, T3 a3, T4 a4,T5 a5)
    {
        typedef Core::TArg<T1,T2,T3> Arg_t;
        Gen_DECLARATE;
        mLauncher = new Strategy_t( Arg_t(a1,a2,a3,a4,a5) );
    }

    template<class T1, class T2, class T3, class T4, class T5, class T6>
    Executer(T1 a1, T2 a2, T3 a3, T4 a4,T5 a5, T6 a6)
    {
        typedef Core::TArg<T1,T2,T3> Arg_t;
        Gen_DECLARATE;
        mLauncher = new Strategy_t( Arg_t(a1,a2,a3,a4,a5,a6) );
    }

    template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
    Executer(T1 a1, T2 a2, T3 a3, T4 a4,T5 a5, T6 a6,T7 a7)
    {
        typedef Core::TArg<T1,T2,T3> Arg_t;
        Gen_DECLARATE;
        mLauncher = new Strategy_t( Arg_t(a1,a2,a3,a4,a5,a6,a7) );
    }

//-------------------------------------------------------

    virtual float Execute(const float seconds) { return mLauncher->Execute(seconds); }
    virtual ILauncher_t* Copy(void) const      { return new Executer(mLauncher); }
    virtual bool IsFinished(void) const        { return true; }
    virtual void Accept(Core::Inspector& inspector){  }
protected:
    ILauncher_t* mLauncher;
};
//-------------------------------------------------------------------------------------------------------------
#define Gen_Return typename Core::TParseArg< Core::TArg<T> >::Strategy_t
template<class T>
Gen_Return Execute(T function)
{
    typedef Core::TArg<T> Arg_t;
    Gen_DECLARATE;
    return Strategy_t( Arg_t(function) );
}
#undef Gen_Return

#define Gen_Return typename Core::TParseArg< Core::TArg<T1,T2> >::Strategy_t
template<class T1, class T2>
Gen_Return Execute(T1 a1, T2 a2)
{
    typedef Core::TArg<T1,T2> Arg_t;
    Gen_DECLARATE;
    return Strategy_t( Arg_t(a1,a2) );
}
#undef Gen_Return

#define Gen_Return typename Core::TParseArg< Core::TArg<T1,T2,T3> >::Strategy_t
template<class T1, class T2, class T3>
Gen_Return Execute(T1 a1, T2 a2, T3 a3)
{
    typedef Core::TArg<T1,T2,T3> Arg_t;
    Gen_DECLARATE;
    return Strategy_t( Arg_t(a1,a2,a3) );
}
#undef Gen_Return

#define Gen_Return typename Core::TParseArg< Core::TArg<T1,T2,T3,T4> >::Strategy_t
template<class T1, class T2, class T3, class T4>
Gen_Return Execute(T1 a1, T2 a2, T3 a3, T4 a4)
{
    typedef Core::TArg<T1,T2,T3,T4> Arg_t;
    Gen_DECLARATE;
    return Strategy_t( Arg_t(a1,a2,a3,a4) );
}
#undef Gen_Return

#define Gen_Return typename Core::TParseArg< Core::TArg<T1,T2,T3,T4,T5> >::Strategy_t
template<class T1, class T2, class T3, class T4, class T5>
Gen_Return Execute(T1 a1, T2 a2, T3 a3, T4 a4,T5 a5)
{
    typedef Core::TArg<T1,T2,T3> Arg_t;
    Gen_DECLARATE;
    return Strategy_t( Arg_t(a1,a2,a3,a4,a5) );
}
#undef Gen_Return

#define Gen_Return typename Core::TParseArg< Core::TArg<T1,T2,T3,T4,T5,T6> >::Strategy_t
template<class T1, class T2, class T3, class T4, class T5, class T6>
Gen_Return Execute(T1 a1, T2 a2, T3 a3, T4 a4,T5 a5, T6 a6)
{
    typedef Core::TArg<T1,T2,T3> Arg_t;
    Gen_DECLARATE;
    return Strategy_t( Arg_t(a1,a2,a3,a4,a5,a6) );
}
#undef Gen_Return

#define Gen_Return typename Core::TParseArg< Core::TArg<T1,T2,T3,T4,T5,T6,T7> >::Strategy_t
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
Gen_Return Execute(T1 a1, T2 a2, T3 a3, T4 a4,T5 a5, T6 a6,T7 a7)
{
    typedef Core::TArg<T1,T2,T3> Arg_t;
    Gen_DECLARATE;
    return Strategy_t( Arg_t(a1,a2,a3,a4,a5,a6,a7) );
}
#undef Gen_Return


}//namespace Commands

#endif
